package com.fractalist.base.core.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.ArrayList;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.math.BigDecimal;

import java.text.DecimalFormat;

public class StringUtil {
   //~ Static fields/initializers =============================================

   private final static Log log = LogFactory.getLog(StringUtil.class);

   //~ Methods ================================================================

   /**
    * Encode a string using algorithm specified in web.xml and return the
    * resulting encrypted password. If exception, the plain credentials
    * string is returned
    *
    * @param password Password or other credentials to use in authenticating
    *        this username
    * @param algorithm Algorithm used to do the digest
    *
    * @return encypted password based on the algorithm.
    */
   public static String encodePassword(String password, String algorithm) {
      byte[] unencodedPassword = password.getBytes();

      MessageDigest md = null;

      try {
         // first create an instance, given the provider
         md = MessageDigest.getInstance(algorithm);
      } catch (Exception e) {
         log.error("Exception: " + e);

         return password;
      }

      md.reset();

      // call the update method one or more times
      // (useful when you don't know the size of your data, eg. stream)
      md.update(unencodedPassword);

      // now calculate the hash
      byte[] encodedPassword = md.digest();

      StringBuffer buf = new StringBuffer();

      for (int i = 0; i < encodedPassword.length; i++) {
         if ((encodedPassword[i] & 0xff) < 0x10) {
            buf.append("0");
         }

         buf.append(Long.toString(encodedPassword[i] & 0xff, 16));
      }

      return buf.toString();
   }

   /**
    * Encode a string using Base64 encoding. Used when storing passwords
    * as cookies.
    *
    * This is weak encoding in that anyone can use the decodeString
    * routine to reverse the encoding.
    *
    * @param str
    * @return String
    */
   public static String encodeString(String str) {
//      sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
//      return encoder.encodeBuffer(str.getBytes()).trim();
	   try {
		byte[] b=Base64.encodeBase64(str.getBytes("utf-8"));
		return new String(b,"utf-8");
	} catch (UnsupportedEncodingException e) {
		throw new RuntimeException(e);
	}
   }

   /**
    * Decode a string using Base64 encoding.
    *
    * @param str
    * @return String
    */
   public static String decodeString(String str) {
//      sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
      try {
//         return new String(dec.decodeBuffer(str));
    	  byte[] b=Base64.decodeBase64(str.getBytes("utf-8"));
    	  return new String(b,"utf-8");
      } catch (IOException io) {
         throw new RuntimeException(io);
      }
   }

   public static String shortString(String src, int length) {
      if (src == null)
         return "";
      if (src.length() <= length)
         return src;
      if (length < 3)
         return src.substring(0, length);
      String result = src.substring(0, length - 3);
      return result + "...";
   }

   public static String getDigit(String s) {
      if (s == null)
         return "";
      return s.replaceAll("\\D", "");
   }


//****************以下是框架扩展方法20080808****************************************************/

	//功能:分割符型字符串转换为数组
	  public static String[] split(String as_str, String as_separator) {//input example as_str="a,,b,c,,d", ",",it can return string array splited by as_separator ','
	    if(as_str == null)
	            throw new NullPointerException("字符串不能为空!");
	    if(as_separator == null)
	            throw new NullPointerException("分隔符不能为空!");
	    if(as_separator.length() == 0)
	            throw new IllegalArgumentException("分隔符不能为空!");

	    ArrayList<String> lal_tmp = new ArrayList<String>();
	    int li_spos = 0;
	    int li_separatorLen = as_separator.length();
	  //如果尾字符串为标记符as_separator，则去掉它
	    if(as_str.substring(as_str.length() - li_separatorLen, as_str.length()).equals(as_separator)){
	      String ls_str = as_str.substring(0,as_str.length() - li_separatorLen);
	      as_str = ls_str;
	    }
	    int li_epos = as_str.indexOf(as_separator);
	    while(li_epos != -1) {
	      lal_tmp.add(as_str.substring(li_spos, li_epos));
	      li_spos = li_epos + li_separatorLen;
	      li_epos = as_str.indexOf(as_separator, li_spos);
	    }
	    lal_tmp.add(as_str.substring(li_spos,as_str.length()));
	    String[] ls_result = new String[lal_tmp.size()];
	    lal_tmp.toArray(ls_result);
	    return ls_result;
	}
	//about call:
//		String[] result = split("a,,b,c,,d", ",");
//		for(int i=0; i<result.length; i++)	System.out.println(result[i]);
//将字符串数组，按分割字符串，拼接组织成字符串，是split方法的逆过程
	  public static String composeSplit(String[] as_strarr,String as_tag){
		String ls_result="";
		for(int i=0;i<as_strarr.length;i++){
		  ls_result += as_tag + as_strarr[i]  ;
		}
		ls_result = RightTag(ls_result,as_tag);
		return ls_result;
	  }

	  public static String pad(String as_pad,int ai_num){//repeat counted ai_num the string named as_pad,and return summar the value;
	    StringBuffer ls_result= new StringBuffer();

	    for(int i=1;i<=ai_num;i++){
	    	ls_result.append(as_pad) ;
	    }
	    return ls_result.toString();
	  }
	//功能:包含,类似于sql标准语句的in函数 入参as_InStrs为字符串,格式为形如"aa|bb"中包含"aa"返回真,yan_add_20060711
	  public static boolean in(String as_SrcStr,String as_InStrs){
	    boolean lb=false;
	    String[] ls_InStrs=null;
	    //若为空串,返回false
	    if( as_SrcStr==null||as_SrcStr.equals("")|| as_InStrs.equals("") )  return false;

	    ls_InStrs = split( as_InStrs,",");//|

	    for (int i=0;i<ls_InStrs.length;i++){
	      if( as_SrcStr.indexOf(ls_InStrs[i]) >=0 ){
	        lb=true;
	        break;
	      }
	    }

	    return lb;
	  }
	//功能:空值替换,类似于oracle的nvl函数
	  public static String nvl(String as_str,String as_val){//equal nvl function in oracle
	    if(as_str==null) return as_val;
	    if ( (as_str.trim()).length()==0 || as_str.equals("") || as_str.equals("null")){

	    }else{
	      as_val = as_str;
	    }
	    return as_val;
	  }//nvl(String as_str,String as_val)
	//返回首字母大写的字串
	 public static String FirstCharToUpper(String as_str){
	   String ls_rtnstr="";
	   int li_len=0;
	   li_len=as_str.length();
	   ls_rtnstr = as_str.substring(0,1).toUpperCase()+as_str.substring(1,li_len);

	   return ls_rtnstr;
	 }

	  public static String nvl(Object ao_obj1,String as_val1){//equal nvl function in oracle
	    if(ao_obj1==null || ao_obj1.equals("") || ao_obj1.equals("null")) {
	      return as_val1;
	    }else{
	      return ao_obj1.toString().trim();
	    }
	  }//nvl(String as_str,String as_val)

	  //功能：判断字符串是否为空
	  public static boolean isnull(String as_str){
	    if ( as_str==null){//yan_modi_20061229 as_str==null
	      return true;
	    }
	    if ( (as_str.trim()).length()==0 || as_str.equals("")){
	      return true;
	    }
	    return false;
	  }

	  /**
	   * 如果字符串为null、""、"null"都返回true  张睿2012-4-11
	   * @param as_str
	   * @return
	   */
	  public static boolean isnull2(String as_str){
	    if ( as_str==null){
	      return true;
	    }
	    if ( (as_str.trim()).length()==0 || as_str.equals("") ||  as_str.equals("null")){
	      return true;
	    }
	    return false;
	  }

	//@功能：字符串替换，
	  public static String replace(String oldStr, String searchStr, String replaceStr){
	    String outStr = "";
	    oldStr = nvl(oldStr, "");
	    searchStr = nvl(searchStr, "");

	    int iPos = 0;
	    int iLen = searchStr.length();

	    if (oldStr.equals("") || searchStr.equals("") || replaceStr == null)
	      return oldStr;

	    iPos = oldStr.indexOf(searchStr);

	    while (iPos != -1) {
	      outStr += oldStr.substring(0, iPos) + replaceStr;
	      iPos += iLen;
	      if (oldStr.length() > iPos) {
	        oldStr = oldStr.substring(iPos);
	        iPos = oldStr.indexOf(searchStr);
	      } else {
	        oldStr = "";
	        iPos = -1;
	      }
	    }

	    outStr += oldStr;
	    return outStr;
	  }
	//@功能：判断字符串是否在字符数组中
	  public static boolean isStrInArray(String as_Str,String[] strArr){
	    boolean bl=false;
	    for(int i=0;i<strArr.length;i++){
	      if(as_Str.equals( strArr[i])) {
	        bl = true;   return bl;
	      }
	    }
	    return bl;
	  }
	//@功能：对sql字符串解码，其中包含单引号的将其转换
	  public static String sqlEncode(String str){
	    if (StringUtil.nvl(str,"").equals("")){
	       return "";
	    }else{
	      str = StringUtil.replace(str, "'", "''");
	    }
	    return str;
	  }
	//xml字符串解码，对其中包含双引号、<、>...的将其转换
	  public static String xmlEncode(String input) {
	    StringBuffer filtered = null;
	    input = nvl(input,"");
	    filtered = new StringBuffer(input.length());

	    char c;
	    for(int i=0; i<input.length(); i++) {
	      c = input.charAt(i);
	      if (c == '<') {
	        filtered.append("&lt;");
	      } else if (c == '>') {
	        filtered.append("&gt;");
	      } else if (c == '"') {
	        filtered.append("&quot;");
	      } else if (c == '&') {
	        filtered.append("&amp;");
	      } else {
	        filtered.append(c);
	      }
	    }
	    return(filtered.toString());
	  }
	//字符集解码，数据库查询取得字符串解码为中文GB2312字符串
	  public static String dbstringEncode(String as_srcStr,String as_dbtype,int flag)  throws Exception {
//	          if (uiEngine.Const.SYSTEM_DATABASE_TYPE == uiEngine.Const.SECTION_DATABASE_ORACLE) {
//	                  return sourceString;
//	          } else if (uiEngine.Const.SYSTEM_DATABASE_TYPE == uiEngine.Const.SECTION_DATABASE_INFORMIX) {
	     if(flag==1){//0来自数据库的字符串，1提交到数据库的字符串
	       if(as_dbtype.equals("Informix")){//Informix数据库需要字符集转换
	         return new String(as_srcStr.getBytes("GB2312"), "ISO8859-1");
	       }
	     }
	     if(as_dbtype.equals("Oracle")||as_dbtype.equals("Sybase")){//此类数据库不需要解码转换
	       return as_srcStr;
	     }else if(as_dbtype.equals("Informix")){
	       return new String(as_srcStr.getBytes("ISO8859-1"), "GB2312");
	     }else{
	       return new String(as_srcStr.getBytes("ISO8859-1"), "GB2312");
	     }

	   //	          } else
//	                  return new String(sourceString.getBytes("ISO8859-1"), "GB2312");
	  }//end

	  public static String RightTag(String as_str,String as_tag){
	    String ls_rightTag="";
	    int li_pos= as_str.indexOf(as_tag);
	    int li_taglen= as_tag.length();
	    ls_rightTag= as_str.substring(li_pos+li_taglen,as_str.length());
	    return ls_rightTag;
	  }
	  public static String LeftTag(String as_str,String as_tag){
	    String ls_leftTag="";
	    int li_pos= as_str.indexOf(as_tag);
	    ls_leftTag= as_str.substring(0,li_pos);
	    return ls_leftTag;
	  }

	 //把字符串数组变字符串
	 public static String getString(String[] stringDemo){
		StringBuffer sb=new StringBuffer();
		 for(int i=0;i<stringDemo.length;i++){
			 if(i!=stringDemo.length-1){
				 sb.append(stringDemo[i]).append(",");
			 }
			 if(i==stringDemo.length-1){
				 sb.append(stringDemo[i]);
			 }
		 }
		 return sb.toString();
	 }
	//把字符串数组变字符串
		 public static String getStringnew(String[] stringDemo){
			StringBuffer sb=new StringBuffer();
			 for(int i=0;i<stringDemo.length;i++){
				 if(i!=stringDemo.length-1){
					 sb.append(stringDemo[i]).append(";");
				 }
				 if(i==stringDemo.length-1){
					 sb.append(stringDemo[i]);
				 }
			 }
			 return sb.toString();
		 }

	//功能:String类型的数据转换成int型
	  public static int strToInt(String str) {//更改？？
	    if ( StringUtil.nvl(str,"").equals("") ){
	       return 0;
	    }else{
	      try {
	        return Integer.parseInt(str.trim());
	      } catch (Exception ex) {
            ex.printStackTrace();
//            return 0;
	      }
	      return 0;
	    }
	  }

	  /**
	   * String转换成int型，如果String为空，则返回-1
	   * @param str
	   * @return
	   */
	  public static int strToInt2(String str) {
	    if ( StringUtil.nvl(str,"").equals("") ){
	       return -1;
	    }else{
	      try {
	        return Integer.parseInt(str.trim());
	      } catch (Exception ex) {
            ex.printStackTrace();
//            return 0;
	      }
	      return 0;
	    }
	  }

//功能:String类型的数据转换成Integer型
	  public static Integer strToInteger(String str) {//更改？？

		    if ( StringUtil.nvl(str,"").equals("") ){
		       return 0;
		    }else{
		      try {
		        return Integer.valueOf(str.trim());
		      } catch (Exception ex) {
	            ex.printStackTrace();
//	            return 0;
		      }
		      return 0;
		    }
	  }

	//功能:String类型的数据转换成Double型
	  public static Double strToDouble(String str) {//更改？？
		    if ( StringUtil.nvl(str,"").equals("") ){
		       return 0.00;
		    }else{
		      try {
		        return Double.valueOf(str.trim());
		      } catch (Exception ex) {
	            ex.printStackTrace();
//	            return 0;
		      }
		      return 0.00;
		    }
	  }

	 	/**
	 	 * 功能:String类型的数据转换成Double型，保留小数点2位数
	 	 * @param str
	 	 * @return
	 	 */
	  public static String strToDoublestr(String str) {
		    if ( StringUtil.nvl(str,"").equals("") ){
		       return "0.00";
		    }else{
		      try {
		    	DecimalFormat fmt=new DecimalFormat("0.00");
		        return fmt.format(Double.valueOf(str.trim()));
		      } catch (Exception ex) {
	            ex.printStackTrace();
//	            return 0;
		      }
		      return "0.00";
		    }
	  }

	  	/**
	  	 * 功能:String类型的数据转换成Double型，保留小数点4位数
	  	 * @param str
	  	 * @return
	  	 */
	  public static String strToDoubleStr2(String str) {
		    if ( StringUtil.nvl(str,"").equals("") ){
		       return "0.0000";
		    }else{
		      try {
		    	DecimalFormat fmt=new DecimalFormat("0.0000");
		        return fmt.format(Double.valueOf(str.trim()));
		      } catch (Exception ex) {
	            ex.printStackTrace();
		      }
		      return "0.0000";
		    }
	  }

	/**
	 * 功能:Double类型的数据格式化为固定小数4位的字符串
	 * @param str
	 * @return
	 */
	  public static String doubleToStr(Double d) {
		  if (d != null){
			  DecimalFormat fmt=new DecimalFormat("0.0000");
		      return fmt.format(d);
		  }else{
			  return "0.0000";
		  }
	  }

	  public static String strDoubleToIntegerstr(String str) {
		    if ( StringUtil.nvl(str,"").equals("") ){
		       return "0.00";
		    }else{
		      try {
		    	DecimalFormat fmt=new DecimalFormat("0");
		        return fmt.format(Double.valueOf(str.trim()));
		      } catch (Exception ex) {
	            ex.printStackTrace();
//	            return 0;
		      }
		      return "0.00";
		    }
	  }

	  /**
	     * 两个Double数相加
	     * @param v1
	     * @param v2
	     * @return Double
	     */
	    public static Double add(Double v1,Double v2){
	        BigDecimal b1 = new BigDecimal(v1.toString());
	        BigDecimal b2 = new BigDecimal(v2.toString());
	        return b1.add(b2).doubleValue();
	    }

	    /**
	     * 两个Double数相减
	     * @param v1
	     * @param v2
	     * @return Double
	     */
	    public static Double sub(Double v1,Double v2){
	        BigDecimal b1 = new BigDecimal(v1.toString());
	        BigDecimal b2 = new BigDecimal(v2.toString());
	        return b1.subtract(b2).doubleValue();
	    }

	    /**
	     * 两个Double数相乘
	     * @param v1
	     * @param v2
	     * @return Double
	     */
	    public static Double mul(Double v1,Double v2){
	        BigDecimal b1 = new BigDecimal(v1.toString());
	        BigDecimal b2 = new BigDecimal(v2.toString());
	        return b1.multiply(b2).doubleValue();
	    }

	    /**
	     * 两个Double数相除
	     * @param v1
	     * @param v2
	     * @return Double
	     */
	    public static Double div(Double v1,Double v2){
	        BigDecimal b1 = new BigDecimal(v1.toString());
	        BigDecimal b2 = new BigDecimal(v2.toString());
	        return b1.divide(b2,10,BigDecimal.ROUND_HALF_UP).doubleValue();
	    }

	    /**
	     * 两个Double数相除，并保留scale位小数
	     * @param v1
	     * @param v2
	     * @param scale
	     * @return Double
	     */
	    public static Double div(Double v1,Double v2,int scale){
	        if(scale<0){
	            throw new IllegalArgumentException(
	            "The scale must be a positive integer or zero");
	        }
	        BigDecimal b1 = new BigDecimal(v1.toString());
	        BigDecimal b2 = new BigDecimal(v2.toString());
	        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
	    }
	    /**
	     * 正则验证,符合返回false,不符合返回true
	     * @param regex
	     * @param verification
	     * @return
	     */
	    public static boolean RegexString(String regex,String verification){

		if(verification.matches(regex)){
		    return false;//符合回false
		}else{
		    return true;//不符合回true
		}
	    }

	    public static boolean RegexArray(String regex,String[] verifications){

		boolean flag = true;//不符合回true
		if(null == verifications || 0 == verifications.length){
		}else{
		    for(String verification:verifications){
			if(verification.matches(regex)){
			    flag = false;//符合回false
	  		    break;
	  		}
		    }
		}
		return flag;
	    }

	    /**
	     * 数组是否为空
	     * @param arrays
	     * @return
	     */
	    public static boolean isNullByArray(String[] arrays){
		if(null == arrays || 0 == arrays.length){
		    return true;
		}else{
		    return false;
		}
	    }

	    /**
	     * 数组转字符串
	     * @param arrays
	     * @return
	     */
	    public static String arrayToString(String[] arrays){
		if(null == arrays || 0 == arrays.length){
		    return "";
		}else{
		    StringBuffer config = new StringBuffer();
		    for (String id : arrays) {
				config.append(id).append(",");
		    }
		    return config.toString();
		}
	    }

	    /**
	     * 如果str的isnull()验证等于false，则返回str.trim(),否则返回空字符串
	     * @param str
	     * @return
	     */
	    public static String trim(String str){
	    	if(!isnull(str)){
	    		return str.trim();
	    	}else{
	    		return "" ;
	    	}
	    }

	    public static boolean isNumeric(String str){
		    for (int i = str.length();--i>=0;){
			    if (!Character.isDigit(str.charAt(i))){
				    return false;
			    }
		    }
		    return true;
	    }

		 public static void main(String args[]){
			 //System.out.println("结果:" + StringUtil.nvl("null", "") + "--end");
		 }

}